﻿using Microsoft.Win32;
using System;
using System.Windows;
using System.Drawing;
using System.Windows.Media.Imaging;
using System.IO;
using System.Windows.Media;
using System.Windows.Controls;
using QrCodeUtils;
using System.Collections.ObjectModel;
using ZXing;
using QrCodeUtils.Utils;
using System.Collections.Generic;
using System.Collections;
using ZXing.QrCode;
using ZXing.Common;
using System.Drawing.Imaging;
using OpenCvSharp;

namespace ImageRounded
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : System.Windows.Window
    {
        public Bitmap doBitmap ;
        private ObservableCollection<OCRListModel> OCRListData = new ObservableCollection<OCRListModel>();
        public MainWindow()
        {
            InitializeComponent();
            OCRListView.DataContext = OCRListData;
            OCRListView.ItemsSource = OCRListData;
            QrCodeSize.Text = "500,500";
            DebugPath.Text = System.Windows.Forms.Application.StartupPath;
        }

        private void SelectImage_Click(object sender, RoutedEventArgs e)
        {
            OCRListData.Clear();//清空上一次的识别内容；
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "图片文件(*.jpg,*.png)|*.jpg;*.png;*.jpeg";//规定指定的格式
            dialog.Multiselect = true;//是否可以多选
            if (dialog.ShowDialog() == true)
            {
                foreach (String fileName in dialog.FileNames)
                {
                    OCRListModel ocrModel = new OCRListModel();
                    ocrModel.ImagePath = fileName;
                    String[] fileNameList = fileName.Split('\\');
                    ocrModel.ImageName = fileNameList[fileNameList.Length-1];
                    OCRListData.Add(ocrModel);
                    using (Bitmap bitImage = new Bitmap(fileName))
                    {
                        FilePath.Text = fileName;
                        BitmapImage bitmapImage = BitmapToBitmapImageFromBitmap(bitImage);
                        ImagePreview.Source = bitmapImage;
                    }
                }
            }
        }

        private void OutPutPath_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {

        }

        private void OperationBtn_Click(object sender, RoutedEventArgs e)
        {
            if (OCRListData.Count == 0)
            {
                MessageBox.Show("请先导入图像");
                return;
            }
            foreach (OCRListModel ocrModel in OCRListData)
            {
                if (File.Exists(ocrModel.ImagePath))
                {
                    Mat mat = Cv2.ImRead(ocrModel.ImagePath);
                    String qrcode = OcrUtil.DetectImageQrCode(mat, ocrModel.ImagePath, DateTime.Now.ToString("yyyyMMddHHmmssfff"),true);
                    if (qrcode != "0")
                        ocrModel.Context = qrcode;
                }
            }
        }

        private void OutPutBtn_Click(object sender, RoutedEventArgs e)
        {
            this.OutPut2Text();
        }

        public static BitmapImage BitmapToBitmapImageFromBitmap(Bitmap bitmap)
        {
            #region
            BitmapImage bitmapImage = new BitmapImage();
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = new MemoryStream(ms.ToArray());
                bitmapImage.EndInit();
            }
            return bitmapImage;
            #endregion
        }

        /// <summary>
        /// ImageSource to Bitmap
        /// </summary>
        /// <param name="imageSource"></param>
        /// <returns></returns>
        public static System.Drawing.Bitmap ImageSourceToBitmap(ImageSource imageSource)
        {
            BitmapSource m = (BitmapSource)imageSource;

            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(m.PixelWidth, m.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); // 坑点：选Format32bppRgb将不带透明度

            System.Drawing.Imaging.BitmapData data = bmp.LockBits(
            new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);

            m.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
            bmp.UnlockBits(data);

            return bmp;
        }

        private void comboBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            var c = comboBox.SelectedItem;
            ComboBoxItem changeC = (ComboBoxItem)c;
            if (null != createQRGrid)

            {
                if (changeC.Name.Equals("createQR"))
                {
                    SelectImageGrid.Visibility = Visibility.Collapsed;
                    createQRGrid.Visibility = Visibility.Visible;
                    normalQRGrid.Visibility = Visibility.Collapsed;
                    invocieQRGrid.Visibility = Visibility.Collapsed;
                    OCRListView.Visibility = Visibility.Collapsed;
                }
                else if (changeC.Name.Equals("normalQR"))
                {
                    SelectImageGrid.Visibility = Visibility.Visible;
                    createQRGrid.Visibility = Visibility.Collapsed;
                    normalQRGrid.Visibility = Visibility.Visible;
                    invocieQRGrid.Visibility = Visibility.Collapsed;
                    OCRListView.Visibility = Visibility.Visible;
                }
                else if (changeC.Name.Equals("invocieQR"))
                {
                    SelectImageGrid.Visibility = Visibility.Visible;
                    createQRGrid.Visibility = Visibility.Collapsed;
                    normalQRGrid.Visibility = Visibility.Collapsed;
                    invocieQRGrid.Visibility = Visibility.Visible;
                    OCRListView.Visibility = Visibility.Visible;
                }
            }
        }

        private void OCRList_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            IList listBox = OCRListView.SelectedItems;
            foreach (OCRListModel group in listBox)
            {
                using (Bitmap bitImage = new Bitmap(group.ImagePath))
                {
                    BitmapImage bitmapImage = BitmapToBitmapImageFromBitmap(bitImage);
                    ImagePreview.Source = bitmapImage;
                }
            }
        }

        private void IsDebugModel_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var c = IsDebugModel.SelectedItem;
            ComboBoxItem IsDebugModelC = (ComboBoxItem)c;
            if (null != DebugPathGrid)
            {
                if (IsDebugModelC.Name.Equals("yes"))
                    DebugPathGrid.Visibility = Visibility.Visible;
                else if (IsDebugModelC.Name.Equals("no"))
                    DebugPathGrid.Visibility = Visibility.Collapsed;
            }
        }

        private void normalQRBtn_Click(object sender, RoutedEventArgs e)
        {
            if (OCRListData.Count == 0)
            {
                MessageBox.Show("请先导入图像");
                return;
            }
            foreach (OCRListModel ocrModel in OCRListData)
            {
                if (File.Exists(ocrModel.ImagePath))
                {
                    Bitmap bitmap = new Bitmap(ocrModel.ImagePath);
                    LuminanceSource source = new BitmapLuminanceSource(CommenUtils.MakeGrayscale3(bitmap));
                    //LuminanceSource source = new BitmapLuminanceSource(QrBitmap);
                    var binarizer = new ZXing.Common.GlobalHistogramBinarizer(source);
                    var binBitmap = new BinaryBitmap(binarizer);
                    var hints = new Dictionary<DecodeHintType, object>();
                    //hints.Add(DecodeHintType.OTHER, 15);
                    //hints.Add(DecodeHintType.TRY_HARDER_WITHOUT_ROTATION, true);
                    hints.Add(DecodeHintType.TRY_HARDER, true);
                    hints.Add(DecodeHintType.CHARACTER_SET, "utf-8");
                    var result = new MultiFormatReader().decode(binBitmap, hints);
                    if (result != null)
                    {
                        ocrModel.Context = result.Text;
                    }
                }
            }
        }

        private void normalQROutPutBtn_Click(object sender, RoutedEventArgs e)
        {
            this.OutPut2Text();
        }

        public void OutPut2Text()
        {
            #region
            if (OCRListData.Count != 0)
            {
                if (!Directory.Exists(System.Windows.Forms.Application.StartupPath + "\\Results"))
                {
                    Directory.CreateDirectory(System.Windows.Forms.Application.StartupPath + "\\Results");
                }
                String LogAddress = System.Windows.Forms.Application.StartupPath + "\\Results\\" + DateTime.Now.ToString("yyyy-MM-dd_HH mm ssfff") + "_Results.txt";
                StreamWriter fs = new StreamWriter(LogAddress, true);
                foreach (OCRListModel o in OCRListData)
                {
                    fs.WriteLine("图像名称：" + o.ImageName);
                    fs.WriteLine("识别内容：" + o.Context);
                    fs.WriteLine();
                }
                fs.Close();
               
                Clipboard.SetDataObject(System.Windows.Forms.Application.StartupPath + "\\Results");
                MessageBox.Show("导出完成，路径：\n"+ System.Windows.Forms.Application.StartupPath + "\\Results \n已复制路径到粘贴板");
            }
            #endregion
        }

        private void OutPutQrCodeBtn_Click(object sender, RoutedEventArgs e)
        {
            if (OutPutCodeName.Text.Equals(""))
            {
                MessageBox.Show("导出文件名为空！");
                return;
            }
            System.Windows.Forms.FolderBrowserDialog folder = new System.Windows.Forms.FolderBrowserDialog();
            if (folder.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string filePath = folder.SelectedPath;
                Bitmap bitmap = ImageSourceToBitmap(ImagePreview.Source);
                bitmap.Save(filePath+"\\"+ OutPutCodeName.Text+".png", ImageFormat.Png);
                MessageBox.Show("导出成功！");
            }
        }

        private void CreateCodeBtn_Click(object sender, RoutedEventArgs e)
        {
            try {
                String[] wh = QrCodeSize.Text.Split(',');
                if (wh.Length != 2)
                {
                    MessageBox.Show("图像大小格式输入有误！");
                    return;
                }
                int w = int.Parse(wh[0]);
                int h = int.Parse(wh[1]);
                BarcodeWriter writer = new BarcodeWriter();
                var c = BarCodeType.SelectedItem;
                ComboBoxItem barCodeType = (ComboBoxItem)c;
                if (CreateContent.Text == "")
                {
                    MessageBox.Show("请先输入需要生成的文本！");
                    return;
                }
                Bitmap map = new Bitmap(10, 10);
                if (barCodeType.Name.Equals("BarCode"))
                {

                    //使用ITF 格式，不能被现在常用的支付宝、微信扫出来
                    //如果想生成可识别的可以使用 CODE_128 格式
                    //writer.Format = BarcodeFormat.ITF;
                    var cc = BarCodeFormatComboBox.SelectedItem;
                    ComboBoxItem barCodeFormatComboBox = (ComboBoxItem)cc;
                    BarcodeFormat o = (BarcodeFormat)Enum.Parse(typeof(BarcodeFormat), barCodeFormatComboBox.Name);
                    writer.Format = o;
                    EncodingOptions options = new EncodingOptions()
                    {
                        Width = w,
                        Height = h,
                        Margin = 2
                    };
                    writer.Options = options;
                    map = writer.Write(CreateContent.Text);
                }
                else
                {
                    writer.Format = BarcodeFormat.QR_CODE;
                    QrCodeEncodingOptions options = new QrCodeEncodingOptions();
                    options.DisableECI = true;
                    //设置内容编码
                    options.CharacterSet = "UTF-8";
                    //设置二维码的宽度和高度
                    options.Width = w;
                    options.Height = h;
                    //设置二维码的边距,单位不是固定像素
                    options.Margin = 1;
                    writer.Options = options;
                    map = writer.Write(CreateContent.Text);
                }

                BitmapImage bitmapImage = BitmapToBitmapImageFromBitmap(map);
                ImagePreview.Source = bitmapImage;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void SelectLogo_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {

        }

        private void BarCodeType_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var c = BarCodeType.SelectedItem;
            ComboBoxItem barCodeType = (ComboBoxItem)c;
            if (BarCodeTypeGrid!=null)
            { 
                if (barCodeType.Name.Equals("QrCode"))
                {
                    QrCodeSize.Text = "500,500";
                    BarCodeTypeGrid.Visibility = Visibility.Collapsed;
                    SelectLogoGrid.Visibility = Visibility.Visible;
                }
                else
                {
                    QrCodeSize.Text = "500,150";
                    BarCodeTypeGrid.Visibility = Visibility.Visible;
                    SelectLogoGrid.Visibility = Visibility.Collapsed;
                }
            }
        }
    }
}
